﻿//===================================================================================
// Copyright (c) Ryan Garrett.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===================================================================================
using System;
using System.Collections.Generic;

namespace Caffeine.Core.Validation
{
    internal sealed class NullableValueTypeValidationRule<T> : ValueTypeValidationRule<Nullable<T>> where T : struct
    {
        #region Constructors

        public NullableValueTypeValidationRule
        (
            Boolean nonDefaultValueRequired,
            Boolean ignoreCommitted,
            T minValue,
            T maxValue,
            String valueRequiredMessage,
            String minErrorFormatString,
            String maxErrorFormatString
        )   : base(nonDefaultValueRequired, ignoreCommitted, minValue, maxValue, valueRequiredMessage, minErrorFormatString, maxErrorFormatString, true)
        {
        }

        #endregion

        #region Protected

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
        protected override void OnValidate(ModelProperty<Nullable<T>> property, ref IEnumerable<ValidationError> errors, ref Boolean isValid)
        {
            Nullable<T> value = property.Value;
            isValid = false;

            if (value == null)
            {
                //If the NonDefaultValueRequired flag is true, the value would have been considered invalid
                //in the base class. If this block executes, NonDefaultValueRequired must be set to false. Meaning
                //null is a valid value.
                isValid = true;
            }
            else
            {
                ValueTypeValidationRule<T>.CheckIsValid
                (
                    property.Parent.AddError,
                    value.Value,
                    MinValue.Value,
                    MaxValue.Value,
                    MinErrorFormatString,
                    MaxErrorFormatString,
                    ref errors,
                    ref isValid
                );
            }
        }

        #endregion
    }
}
